import dayjs from "dayjs";

import calculateOverlapMinutes from "./calculateOverlapMinutes.js";

export default generateDayItems;

function generateDayItems(
  rawData,
  stepMinutes = 30,
  startDate,
  endDate,
  valueType = "weighted"
) {
  if (!rawData || rawData.length === 0) {
    console.info("generateDayItems: rawData is empty");
    return [];
  }
  const dayItems = new Array();
  const startDay = dayjs(startDate).startOf("day");
  const endDay = dayjs(endDate).endOf("day");
  let currentRawDataIndex = 0;
  // 生成日期范围内的每一天
  for (
    let currentDay = startDay;
    currentDay.isSameOrBefore(endDay, "day");
    currentDay = currentDay.add(1, "day")
  ) {
    const currentDayItem = {
      day: currentDay,
      date: currentDay.format("YYYY-MM-DD"),
      shortDate: currentDay.format("MM/DD"),
      cellItems: [],
      maxValue: 0,
      accumulation: 0,
    };
    // 生成每个日期的小时数据
    for (let minute = 0; minute < 1440; minute += stepMinutes) {
      const moment = currentDay.add(minute, "minute");
      const moment2 = moment.add(stepMinutes, "minute");
      const currentCellItem = {
        day: currentDayItem.day,
        date: currentDayItem.date,
        shortDate: currentDayItem.shortDate,
        moment,
        moment2,
        time: moment.format("HH:mm:ss"),
        shortTime: moment.format("HH:mm"),
        value: 0,
        valueWeighted: 0,
        valueAvg: 0,
        valueMax: 0,
        valueMin: 0,
        valueContent: [],
        relatedRecords: [],
      };

      // 计算该时间段内的值
      for (let i = currentRawDataIndex; i < rawData.length; i++) {
        const currentRecord = rawData[i];
        // 检查是否有重叠
        if (
          currentCellItem.moment.isBefore(currentRecord.endTime) &&
          currentCellItem.moment2.isAfter(currentRecord.startTime)
        ) {
          const overlapMinutes = calculateOverlapMinutes(
            currentCellItem.moment,
            currentCellItem.moment2,
            currentRecord.startTime,
            currentRecord.endTime
          );
          if (overlapMinutes > 0) {
            currentCellItem.valueContent.push({
              count: currentRecord.count,
              minutes: overlapMinutes,
            });
            currentCellItem.relatedRecords.push(currentRecord);
          }
        } else if (currentCellItem.moment2.isBefore(currentRecord.startTime)) {
          // 如果记录的开始时间在当前时间段之后，跳出循环
          currentRawDataIndex = i >= 2 ? i - 2 : 0; // 优化下次循环的起始位置
          break;
        }
      }

      // 计算统计值
      currentCellItem.valueMax = Math.max(
        ...currentCellItem.valueContent.map((v) => v.count)
      );
      currentCellItem.valueMin = Math.min(
        ...currentCellItem.valueContent.map((v) => v.count)
      );
      currentCellItem.valueAvg = Math.round(
        currentCellItem.valueContent.reduce(
          (acc, curr) => acc + curr.count,
          0
        ) / currentCellItem.valueContent.length
      );
      currentCellItem.valueWeighted = Math.round(
        currentCellItem.valueContent.reduce(
          (acc, curr) =>
            acc +
            (curr.count * curr.minutes) /
              currentCellItem.valueContent.reduce(
                (acc, curr) => acc + curr.minutes,
                0
              ),
          0
        )
      );

      if (valueType === "weighted") {
        currentCellItem.value = currentCellItem.valueWeighted;
      } else if (valueType === "avg") {
        currentCellItem.value = currentCellItem.valueAvg;
      } else if (valueType === "max") {
        currentCellItem.value = currentCellItem.valueMax;
      } else if (valueType === "min") {
        currentCellItem.value = currentCellItem.valueMin;
      } else {
        currentCellItem.value = currentCellItem.valueWeighted;
      }

      // 添加到当前日期的cellItems
      currentDayItem.cellItems.push(currentCellItem);

      // 更新当前日期的最大值
      currentDayItem.maxValue = Math.max(
        currentDayItem.maxValue,
        currentCellItem.valueMax
      );

      // 更新当前日期的总值
      currentDayItem.accumulation += currentCellItem.value * stepMinutes;
    }

    dayItems.push(currentDayItem);
  }
  return dayItems;
}
